package cn.edu.tju.wallet.domain;

import cn.edu.tju.core.model.BaseEntity;
import jakarta.persistence.*;
import java.math.BigDecimal;

/**
 * VIP等级实体（充血模型）
 * 包含VIP等级数据和等级相关的业务逻辑
 */
@Entity
@Table(name = "vip_levels")
public class VipLevel extends BaseEntity {

    @Column(name = "name", nullable = false, length = 50, unique = true)
    private String name;  // VIP等级名称：青铜、白银、黄金、铂金、钻石

    @Column(name = "level", nullable = false)
    private Integer level;  // VIP等级数值（1=青铜，2=白银，3=黄金，4=铂金，5=钻石）

    @Column(name = "min_total_consumption", precision = 19, scale = 2, nullable = false)
    private BigDecimal minTotalConsumption;  // 最低累计消费金额

    @Column(name = "min_total_recharge", precision = 19, scale = 2, nullable = false)
    private BigDecimal minTotalRecharge;  // 最低累计充值金额

    @Column(name = "overdraft_multiplier", precision = 5, scale = 2, nullable = false)
    private BigDecimal overdraftMultiplier;  // 透支限额倍数

    @Column(name = "interest_discount", precision = 5, scale = 2, nullable = false)
    private BigDecimal interestDiscount;  // 利息折扣（1.0=无折扣，0.8=8折）

    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private RuleStatus status = RuleStatus.ACTIVE;  // 等级状态

    @Column(name = "priority", nullable = false)
    private Integer priority = 0;  // 优先级

    // ============================================
    // 构造函数
    // ============================================

    public VipLevel() {}

    public VipLevel(String name, Integer level, BigDecimal minTotalConsumption,
                    BigDecimal minTotalRecharge) {
        this.name = name;
        this.level = level;
        this.minTotalConsumption = minTotalConsumption;
        this.minTotalRecharge = minTotalRecharge;
        this.overdraftMultiplier = BigDecimal.ONE;
        this.interestDiscount = BigDecimal.ONE;
        this.status = RuleStatus.ACTIVE;
        this.priority = level;
    }

    // ============================================
    // 核心业务方法
    // ============================================

    /**
     * 判断用户是否符合该VIP等级（充血模型：等级自己判断适用性）
     * @param totalConsumption 累计消费金额
     * @param totalRecharge 累计充值金额
     * @return 是否符合
     */
    public boolean isApplicable(BigDecimal totalConsumption, BigDecimal totalRecharge) {
        if (this.status != RuleStatus.ACTIVE) return false;

        boolean meetConsumption = totalConsumption.compareTo(this.minTotalConsumption) >= 0;
        boolean meetTotalRecharge = totalRecharge.compareTo(this.minTotalRecharge) >= 0;

        return meetConsumption && meetTotalRecharge;
    }

    /**
     * 计算该VIP等级的透支限额倍数
     * @return 透支限额倍数
     */
    public BigDecimal getOverdraftMultiplier() {
        return this.overdraftMultiplier;
    }

    /**
     * 计算该VIP等级的利息折扣
     * @return 利息折扣（0.0-1.0）
     */
    public BigDecimal getInterestDiscount() {
        return this.interestDiscount;
    }

    /**
     * 计算折扣后需要支付的利息
     * @param originalInterest 原利息
     * @return 折扣后利息
     */
    public BigDecimal calculateDiscountedInterest(BigDecimal originalInterest) {
        if (originalInterest == null || originalInterest.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        return originalInterest.multiply(this.interestDiscount);
    }

    /**
     * 判断等级是否激活
     * @return 是否激活
     */
    public boolean isActive() {
        return this.status == RuleStatus.ACTIVE;
    }

    /**
     * 获取升级到下一等级需要的剩余金额
     * @param totalConsumption 当前累计消费
     * @param totalRecharge 当前累计充值
     * @return 升级条件对象（包含剩余消费和充值金额）
     */
    public UpgradeRequirement getUpgradeRequirement(BigDecimal totalConsumption, BigDecimal totalRecharge) {
        BigDecimal remainingConsumption = BigDecimal.ZERO;
        BigDecimal remainingRecharge = BigDecimal.ZERO;

        if (totalConsumption.compareTo(this.minTotalConsumption) < 0) {
            remainingConsumption = this.minTotalConsumption.subtract(totalConsumption);
        }

        if (totalRecharge.compareTo(this.minTotalRecharge) < 0) {
            remainingRecharge = this.minTotalRecharge.subtract(totalRecharge);
        }

        return new UpgradeRequirement(remainingConsumption, remainingRecharge);
    }

    /**
     * 获取等级的特权描述
     * @return 特权描述字符串
     */
    public String getPrivilegesDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append("透支限额×").append(this.overdraftMultiplier);
        sb.append("，利息").append(this.interestDiscount.multiply(BigDecimal.valueOf(100))).append("%");
        return sb.toString();
    }

    /**
     * 激活等级
     * @return 当前等级对象
     */
    public VipLevel activate() {
        this.status = RuleStatus.ACTIVE;
        return this;
    }

    /**
     * 停用等级
     * @return 当前等级对象
     */
    public VipLevel deactivate() {
        this.status = RuleStatus.INACTIVE;
        return this;
    }

    /**
     * 设置升级条件
     * @param minTotalConsumption 最低累计消费
     * @param minTotalRecharge 最低累计充值
     * @return 当前等级对象
     */
    public VipLevel setUpgradeRequirements(BigDecimal minTotalConsumption,
                                          BigDecimal minTotalRecharge) {
        this.minTotalConsumption = minTotalConsumption;
        this.minTotalRecharge = minTotalRecharge;
        return this;
    }

    /**
     * 设置VIP特权
     * @param overdraftMultiplier 透支限额倍数
     * @param interestDiscount 利息折扣
     * @return 当前等级对象
     */
    public VipLevel setPrivileges(BigDecimal overdraftMultiplier, BigDecimal interestDiscount) {
        this.overdraftMultiplier = overdraftMultiplier;
        this.interestDiscount = interestDiscount;
        return this;
    }

    /**
     * 验证等级参数的有效性
     * @throws IllegalArgumentException 当参数无效时
     */
    public void validate() {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("VIP等级名称不能为空");
        }
        if (level == null || level <= 0) {
            throw new IllegalArgumentException("VIP等级数值必须大于0");
        }
        if (minTotalConsumption == null || minTotalConsumption.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("最低累计消费金额不能为负数");
        }
        if (minTotalRecharge == null || minTotalRecharge.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("最低累计充值金额不能为负数");
        }
        if (overdraftMultiplier == null || overdraftMultiplier.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("透支限额倍数必须大于0");
        }
        if (interestDiscount == null || interestDiscount.compareTo(BigDecimal.ZERO) < 0 ||
            interestDiscount.compareTo(BigDecimal.ONE) > 0) {
            throw new IllegalArgumentException("利息折扣必须在0到1之间");
        }
    }

    /**
     * 获取等级的详细信息描述
     * @return 等级描述
     */
    public String getDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append(name).append("（等级").append(level).append("）：");
        sb.append("累计消费满").append(minTotalConsumption).append("元，");
        sb.append("累计充值满").append(minTotalRecharge).append("元；");
        sb.append(getPrivilegesDescription());
        return sb.toString();
    }

    // ============================================
    // 内部类：升级条件
    // ============================================
    public static class UpgradeRequirement {
        private final BigDecimal remainingConsumption;
        private final BigDecimal remainingRecharge;

        public UpgradeRequirement(BigDecimal remainingConsumption, BigDecimal remainingRecharge) {
            this.remainingConsumption = remainingConsumption.max(BigDecimal.ZERO);
            this.remainingRecharge = remainingRecharge.max(BigDecimal.ZERO);
        }

        public boolean isMet() {
            return remainingConsumption.compareTo(BigDecimal.ZERO) == 0 &&
                   remainingRecharge.compareTo(BigDecimal.ZERO) == 0;
        }

        public BigDecimal getRemainingConsumption() {
            return remainingConsumption;
        }

        public BigDecimal getRemainingRecharge() {
            return remainingRecharge;
        }

        public String getDescription() {
            if (isMet()) {
                return "已满足升级条件";
            }
            StringBuilder sb = new StringBuilder();
            if (remainingConsumption.compareTo(BigDecimal.ZERO) > 0) {
                sb.append("还需消费").append(remainingConsumption).append("元");
            }
            if (remainingRecharge.compareTo(BigDecimal.ZERO) > 0) {
                if (sb.length() > 0) sb.append("，");
                sb.append("还需充值").append(remainingRecharge).append("元");
            }
            return sb.toString();
        }
    }

    // ============================================
    // Getter and Setter
    // ============================================

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    public BigDecimal getMinTotalConsumption() {
        return minTotalConsumption;
    }

    public void setMinTotalConsumption(BigDecimal minTotalConsumption) {
        this.minTotalConsumption = minTotalConsumption;
    }

    public BigDecimal getMinTotalRecharge() {
        return minTotalRecharge;
    }

    public void setMinTotalRecharge(BigDecimal minTotalRecharge) {
        this.minTotalRecharge = minTotalRecharge;
    }

    public BigDecimal getOverdraftMultiplierValue() {
        return overdraftMultiplier;
    }

    public void setOverdraftMultiplier(BigDecimal overdraftMultiplier) {
        this.overdraftMultiplier = overdraftMultiplier;
    }

    public BigDecimal getInterestDiscountValue() {
        return interestDiscount;
    }

    public void setInterestDiscount(BigDecimal interestDiscount) {
        this.interestDiscount = interestDiscount;
    }

    public RuleStatus getStatus() {
        return status;
    }

    public void setStatus(RuleStatus status) {
        this.status = status;
    }

    public Integer getPriority() {
        return priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    // ============================================
    // 等级状态枚举
    // ============================================
    public enum RuleStatus {
        ACTIVE,     // 激活
        INACTIVE    // 未激活
    }
}
